In [ ]:
import pyVHR as vhr
import numpy as np

from pyVHR.analysis.pipeline import Pipeline
vhr.plot.VisualizeParams.renderer = 'notebook'  # colab or 'notebook'

dataset_name = 'lgi_ppgi'          
video_DIR = '../datasets/LGI-PPGI/' 
BVP_DIR = '../datasets/LGI-PPGI/'    # dir containing BVPs GT

dataset = vhr.datasets.datasetFactory(dataset_name, videodataDIR= video_DIR, BVPdataDIR= BVP_DIR)
allvideo = dataset.videoFilenames
allground = dataset.sigFilenames
pipeline = Pipeline()
2022-09-24 23:29:53.391509: I tensorflow/stream_executor/platform/default/dso_loader.cc:53] Successfully opened dynamic library libcudart.so.11.0
In [ ]:
def get_comparison(met, app):
    BPMs = []
    times = []
    uncerts = []
    titles = []

    bpmgt ,timegt = vhr.datasets.lgi_ppgi.LGI_PPGI(videodataDIR= allvideo[0], BVPdataDIR= allground[0]).readSigfile(filename= allground[0]).getBPM()

    for i in allvideo:
        txt = i.split('/')[4]
        txt_ = txt.split('_')
        titles.append(( txt_[0],txt_[1]))

    methods = ['cupy_POS', 'torch_CHROM', 'cupy_CHROM']
    for method in methods:
        temp = pipeline.run_on_video(allvideo[0],cuda = True, roi_method=met, roi_approach=app, method= method )
        BPMs.append(temp[1])
        times.append(temp[0])
        uncerts.append(temp[2])

    cupy_POS = [BPMs[0], times[0], 'cupy POS']
    torch_CHROM = [BPMs[1], times[1], 'torch CHROM']
    cupy_CHROM = [BPMs[2], times[2], 'cupy_CHROM']
    gT = [bpmgt, timegt, "Ground Truth"]

    vhr.plot.visualize_BPMs([cupy_POS, torch_CHROM, cupy_CHROM, gT])
In [ ]:
cupy_POS = [BPMs[0], times[0], 'cupy POS']
torch_CHROM = [BPMs[1], times[1], 'torch CHROM']
cupy_CHROM = [BPMs[2], times[2], 'cupy_CHROM']
gT = [bpmgt, timegt, "Ground Truth"]

vhr.plot.visualize_BPMs([cupy_POS, torch_CHROM, cupy_CHROM, gT])

Comparison of various methods¶

  • ### Convex hull (FaceMesh) extraction, and holistic approach
In [ ]:
get_comparison('convexhull','holistic')
# CUDA devices:  1
# device number  0 :  NVIDIA GeForce RTX 3060

Processing Video: ../datasets/LGI-PPGI/alex/alex_talk/cv_camera_sensor_stream_handler.avi

BVP extraction with method: cupy_POS

BPM estimation with: welch

...done!

# CUDA devices:  1
# device number  0 :  NVIDIA GeForce RTX 3060

Processing Video: ../datasets/LGI-PPGI/alex/alex_talk/cv_camera_sensor_stream_handler.avi

BVP extraction with method: torch_CHROM

BPM estimation with: welch

...done!

# CUDA devices:  1
# device number  0 :  NVIDIA GeForce RTX 3060

Processing Video: ../datasets/LGI-PPGI/alex/alex_talk/cv_camera_sensor_stream_handler.avi

BVP extraction with method: cupy_CHROM

BPM estimation with: welch

...done!

  • ### Convex hull (Face Mesh) extraction, and patch-based approach
In [ ]:
get_comparison('convexhull', 'patches')
# CUDA devices:  1
# device number  0 :  NVIDIA GeForce RTX 3060

Processing Video: ../datasets/LGI-PPGI/alex/alex_talk/cv_camera_sensor_stream_handler.avi
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
/tmp/ipykernel_1084498/839987791.py in <module>
----> 1 get_comparison('convexhull', 'patches')

/tmp/ipykernel_1084498/2707220206.py in get_comparison(met, app)
     14     methods = ['cupy_POS', 'torch_CHROM', 'cupy_CHROM']
     15     for method in methods:
---> 16         temp = pipeline.run_on_video(allvideo[0],cuda = True, roi_method=met, roi_approach=app, method= method )
     17         BPMs.append(temp[1])
     18         times.append(temp[0])

/mnt/HDD/israel/miniconda3/envs/pyvhr/lib/python3.9/site-packages/pyVHR-1.0.2-py3.9.egg/pyVHR/analysis/pipeline.py in run_on_video(self, videoFileName, cuda, roi_method, roi_approach, method, bpm_type, pre_filt, post_filt, verb)
    123         # -- color threshold - applied only with patches
    124         if roi_approach == 'patches':
--> 125             filtered_windowed_sig = apply_filter(windowed_sig,
    126                                                  rgb_filter_th,
    127                                                  params={'RGB_LOW_TH':  75,

/mnt/HDD/israel/miniconda3/envs/pyvhr/lib/python3.9/site-packages/pyVHR-1.0.2-py3.9.egg/pyVHR/BVP/filters.py in apply_filter(windowed_sig, filter_func, fps, params)
     47             filt_temp = filter_func(sig)
     48         else:
---> 49             filt_temp = filter_func(sig, **params)
     50         if transform:
     51             filt_temp = np.squeeze(filt_temp, axis=1)

/mnt/HDD/israel/miniconda3/envs/pyvhr/lib/python3.9/site-packages/pyVHR-1.0.2-py3.9.egg/pyVHR/BVP/filters.py in rgb_filter_th(sig, **kargs)
    169         sig, np.int32(kargs['RGB_LOW_TH']), np.int32(kargs['RGB_HIGH_TH']))
    170     if np.sum(goodidx) == 0:
--> 171         raise Exception(f"Too tight thresholds {(kargs['RGB_LOW_TH'], kargs['RGB_HIGH_TH'])} for pixel colors, blank face mask!")
    172     return np.copy(sig[np.argwhere(goodidx).flatten()])

Exception: Too tight thresholds (75, 230) for pixel colors, blank face mask!
  • ### Face Parsing (BiseNet) extraction, and holistic approach
In [ ]:
get_comparison('faceparsing', 'holistic')
# CUDA devices:  1
# device number  0 :  NVIDIA GeForce RTX 3060

Processing Video: ../datasets/LGI-PPGI/alex/alex_talk/cv_camera_sensor_stream_handler.avi

BVP extraction with method: cupy_POS

BPM estimation with: welch

...done!

# CUDA devices:  1
# device number  0 :  NVIDIA GeForce RTX 3060

Processing Video: ../datasets/LGI-PPGI/alex/alex_talk/cv_camera_sensor_stream_handler.avi

BVP extraction with method: torch_CHROM

BPM estimation with: welch

...done!

# CUDA devices:  1
# device number  0 :  NVIDIA GeForce RTX 3060

Processing Video: ../datasets/LGI-PPGI/alex/alex_talk/cv_camera_sensor_stream_handler.avi

BVP extraction with method: cupy_CHROM

BPM estimation with: welch

...done!

  • ### Face Parsing (BiseNet) extraction, and patches approach
In [ ]:
get_comparison('faceparsing', 'patches')
# CUDA devices:  1
# device number  0 :  NVIDIA GeForce RTX 3060

Processing Video: ../datasets/LGI-PPGI/alex/alex_talk/cv_camera_sensor_stream_handler.avi
---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
/tmp/ipykernel_1084498/485424119.py in <module>
----> 1 get_comparison('faceparsing', 'patches')

/tmp/ipykernel_1084498/2707220206.py in get_comparison(met, app)
     14     methods = ['cupy_POS', 'torch_CHROM', 'cupy_CHROM']
     15     for method in methods:
---> 16         temp = pipeline.run_on_video(allvideo[0],cuda = True, roi_method=met, roi_approach=app, method= method )
     17         BPMs.append(temp[1])
     18         times.append(temp[0])

/mnt/HDD/israel/miniconda3/envs/pyvhr/lib/python3.9/site-packages/pyVHR-1.0.2-py3.9.egg/pyVHR/analysis/pipeline.py in run_on_video(self, videoFileName, cuda, roi_method, roi_approach, method, bpm_type, pre_filt, post_filt, verb)
    123         # -- color threshold - applied only with patches
    124         if roi_approach == 'patches':
--> 125             filtered_windowed_sig = apply_filter(windowed_sig,
    126                                                  rgb_filter_th,
    127                                                  params={'RGB_LOW_TH':  75,

/mnt/HDD/israel/miniconda3/envs/pyvhr/lib/python3.9/site-packages/pyVHR-1.0.2-py3.9.egg/pyVHR/BVP/filters.py in apply_filter(windowed_sig, filter_func, fps, params)
     47             filt_temp = filter_func(sig)
     48         else:
---> 49             filt_temp = filter_func(sig, **params)
     50         if transform:
     51             filt_temp = np.squeeze(filt_temp, axis=1)

/mnt/HDD/israel/miniconda3/envs/pyvhr/lib/python3.9/site-packages/pyVHR-1.0.2-py3.9.egg/pyVHR/BVP/filters.py in rgb_filter_th(sig, **kargs)
    169         sig, np.int32(kargs['RGB_LOW_TH']), np.int32(kargs['RGB_HIGH_TH']))
    170     if np.sum(goodidx) == 0:
--> 171         raise Exception(f"Too tight thresholds {(kargs['RGB_LOW_TH'], kargs['RGB_HIGH_TH'])} for pixel colors, blank face mask!")
    172     return np.copy(sig[np.argwhere(goodidx).flatten()])

Exception: Too tight thresholds (75, 230) for pixel colors, blank face mask!